#ifndef __ACTION_H_
#define __ACTION_H_

/**
 * Desc: 事件
 * Auth: 张宇飞
 * Date: 2014-08-01    
 */
#include "config.h"
#include "csbtypes.h"

#ifdef __cplusplus
extern "C" {
#endif

/* 各种条件定义 */
#define CON_BIG_THAN  0x0
#define CON_EQUAL     0x1
#define CON_LESS_THAN 0x2

#define CON_SIGN_TRUE 0x0
#define CON_AND       0x1
#define CON_OR        0x2

#define CON_RES_TO    ':' //变化到
#define CON_RES_ADD   '+' //增加
#define CON_RES_SUB   '-' //减少

#define CON_ME_DRATIO 'D' //正比
#define CON_ME_FIXED  'F' //固定
#define CON_ME_SIN    'S' //正弦(暂时不支持)

/* 永真值条件类型 */
#define CON_ALWAYS_TRUE_TYPE	0xff

typedef struct {
	//符号和条件的位或值:(11)(两个条件的连接1)(符号二2)(符号一2)(条件二8)(条件一8)
	int	tAs;
	float	data0; //值0
	float	data1; //值1
} con_t;

#define CON_GET_TYPE1(tas)	(tas & 0xff)
#define CON_GET_TYPE2(tas)	((tas >> 8) & 0xff)
#define CON_GET_SIGN1(tas)	((tas >> 16) & 0x3)
#define CON_GET_SIGN2(tas)	((tas >> 18) & 0x3)
#define CON_GET_AOR(tas)	((tas >> 20) & 0x1)

/*  描述一个动作的结构 */ 
typedef struct {
	// 条件
	con_t		con;
	int8_t		restype;	//结果类型
	char		conressign;	//结果变化符号
	char		conmesign;	//结果变化方式符号(暂时不支持)
	bool		nforever;	//变化次数是否为永远(对齐位)
	float		resdata;	//结果值
	uint32_t	changetime;	//变化时间
	uint32_t	ntime;		//变化次数
} action_t;

/* 事件作用结果 */
typedef struct {
	int8_t		type;
	char		ressign;
	char		mesign;
	char 		pad;
	float		data;
	uint32_t	n;
} action_eff_t;

/* 事件组 */
typedef struct{
	uint32_t	interval;
	int32_t		sinterval;
	list_t		acs; /* 元素是action_t */
} action_list_t;

/*  事件组 */
typedef list_t* 		ac_t;

/* 返回是否触发了该事件,以控制执行次数 */
typedef bool (*action_handle)(action_t*, void*);
typedef void (*action_eff_handle)(const action_eff_t* eff, void* flag);
/*********************| extern functions |*********************/
extern CSB_DLL uint32_t 	actiondata_read(ac_t* pac, unsigned char* data, const int8_t typeoffset);
extern CSB_DLL void		ac_free(ac_t ac);

extern CSB_DLL void		ac_foreach(ac_t ac, action_handle func,
					   const int32_t ntime, void* flag);
extern CSB_DLL void		action_buf_init();
extern CSB_DLL void		action_buf_end(bool force);
extern CSB_DLL action_t*	action_buf_rent();
extern CSB_DLL void		action_buf_return(action_t* pac);

extern CSB_DLL void		action_eff_buf_init();
extern CSB_DLL void		action_eff_buf_end(bool force);
extern CSB_DLL action_eff_t*	action_eff_buf_rent();
extern CSB_DLL void		action_eff_buf_return(action_eff_t* pace);
extern CSB_DLL void		action_eff_list_for(list_t* pl, action_eff_handle func, void* flag);
extern CSB_DLL void		action_eff_list_clean(list_t* pl);

/* 如果变化方式是正比，变幻符号是变化到，那么需要在外面自己将符号计算得+或者-，而数值为差值微分值 */
extern CSB_DLL action_eff_t*	action_make_action_eff(const action_t* pac);

extern CSB_DLL ac_t 		ac_buf_copy(const ac_t src);

/* 判定条件是否满足 */
#define action_con_match(d, s, da) \
	((CON_EQUAL == s) ? (d == da): ((CON_LESS_THAN == s) ? (d < da) : (d > da)))
/* 判定两个条件是否都满足 */
#define action_2con_match(c1, c2, s)	((CON_OR == s) ? (c1 || c2) : (c1 && c2))
/* 变化的结果 */
#define action_res2(src, s, d) \
	((CON_RES_TO == s) ? d : ((CON_RES_ADD == s) ? (src + d) : (src - d)))


#ifdef __cplusplus
} /* end extern C */
#endif


#endif /* end of include guard: __ACTION_H_ */
